//
// This file is part of Adguard for iOS (https://github.com/AdguardTeam/AdguardForiOS).
// Copyright © Adguard Software Limited. All rights reserved.
//
// Adguard for iOS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Adguard for iOS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Adguard for iOS. If not, see <http://www.gnu.org/licenses/>.
//

import Foundation

public extension Array where Element: Equatable {
    /// Returns true if all elements are equal
    var allElementsAreEqual: Bool {
        if let firstElem = self.first {
            for elem in self {
                if elem != firstElem {
                    return false
                }
            }
        }
        return true
    }

    /// Returns true if `isOrderedBefore` returns true for all element pairs
    func isSorted(isOrderedBefore: (Element, Element) -> Bool) -> Bool {
        for i in 1..<self.count {
            if !isOrderedBefore(self[i-1], self[i]) {
                return false
            }
        }
        return true
    }
}

public extension Array where Element: Hashable {
    /// Returns array of duplicate elements
    /// Returns empty array if there are no duplicates
    var duplicates: [Element] {
        var uniqueElements: Set<Element> = []
        return self.compactMap {
            if uniqueElements.contains($0) {
                return $0
            } else {
                uniqueElements.insert($0)
                return nil
            }
        }
    }

    /// Returns array of unique elements preserving elements order
    var uniqueElements: [Element] {
        var uniqueElements: Set<Element> = []
        return self.compactMap {
            if uniqueElements.contains($0) {
                return nil
            }
            uniqueElements.insert($0)
            return $0
        }
    }
}
